import { render, Component, ObjectProps, CSSStyle, WebComponents, NS, unsafe, BaseProps } from '../../../dist/esm';

// 自定义组件
type MyProps = ObjectProps<MyComponent> & {
	style?: CSSStyle;
	beforeRender?: (this: MyComponent, num: number) => void;
};

class MyComponent extends Component<MyProps> {
	disabled = false;
	render() {
		this.call('beforeRender', 11);
		return (
			<div style={this.props.style}>
				<h2>MyComponent {new Date()}</h2>
				<button
					onClick={() => {
						this.update();
						console.log('MyComponent updated!!');
					}}
				>
					Update Completely
				</button>
			</div>
		);
	}
}

// 自定义 WebComponent 组件
class MyWebComponent extends HTMLDivElement {
	constructor() {
		super();
		this.attachShadow({ mode: 'open' });
		this.shadowRoot?.append(<h2>MyWebComponent</h2>);
	}
	connectedCallback() {
		this.dispatchEvent(new Event('connected'));
		console.log('MyWebComponent connectedCallback!!');
		this.shadowRoot?.append(<div>connectedCallback: {Array.from(this.childNodes)}</div>);
	}
}
// 注册并获得 WebComponent 组件的包装器类型，
// 既可以使用标签名，也可以使用包装器类型来使用组件
const ComponentWrapper = WebComponents.register(MyWebComponent, 'my-web-component', 'div');

// 如果 WebComponent 组件的类名不符合命名规则，需要传递给 register 方法自定义的标签名
class 中文的组件 extends HTMLElement {
	constructor() {
		super();
		this.attachShadow({ mode: 'open' });
		this.shadowRoot?.append(
			<div>
				<h2>中文的组件</h2>
				文字内容...
			</div>
		);
	}
	connectedCallback() {
		this.shadowRoot?.append(<div>connectedCallback: {this.childNodes}</div>);
	}
}
WebComponents.register(中文的组件, 'chinese-component');

// 自定义函数组件，可以没有参数
function SimpleFunction() {
	return (
		<>
			<h2>SimpleFunction</h2>
			<p>p1</p>
			<p>p2</p>
			<input name="name" value="value" />
		</>
	);
}

// 自定义函数组件
type Prop = BaseProps & {
	test?: string;
	style?: string | CSSStyle;
};
function FurtherFunction(props: Prop) {
	return (
		<div name={props.test} style={props.style}>
			<h2>FurtherFunction</h2>
			Children: {props.children}
			<hr />
		</div>
	);
}

render(() => {
	return (
		<div style={{ fontSize: '16pt' }} ref={(d) => console.log('root element created:', d.nodeName)}>
			普通文字
			<br />
			不安全的内容：
			<div innerHTML="<span id='unsafe' style='color: red'>unsafe text</span>">
				{unsafe('<style>#unsafe { font-size: 30pt; }</style>')}
			</div>
			{'特殊符号的文字： > - < - &'}
			<ComponentWrapper
				onconnected={() => {
					console.log('MyWebComponent connected event received!!');
				}}
				style={{ fontSize: '20pt', color: 'green' }}
				ref={(el) => {
					console.log('ComponentWrapper created:', el.nodeName);
				}}
			>
				{[1, 2, 3, 4].map((i) => `text${i}`).join(',')}
			</ComponentWrapper>
			<chinese-component style={{ fontSize: '30pt' }}>
				{[1, 2, 3, 4].map((i) => (
					<span style="padding: 0.5em; font-size: 12pt">span{i}</span>
				))}
			</chinese-component>
			<SimpleFunction />
			<FurtherFunction style={{ fontSize: '18pt' }}>
				{[1, 2, 3, 4].map((i) => (
					<button>button{i}</button>
				))}
			</FurtherFunction>
			<MyComponent
				style={{ fontSize: '20pt', color: 'red' }}
				ref={(m) => {
					console.log('JSX component created:', m);
					m.disabled = true;
				}}
				beforeRender={function (num) {
					console.log('beforeRender:', this.props, num);
				}}
			>
				child text
			</MyComponent>
			<svg width="100" height="100">
				<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
			</svg>
			{/* 如果 SVG 中存在和 HTML 中冲突的标签可以用 Namespace 区分 */}
			<div />
			{NS.svg(() => {
				return (
					<svg width="100" height="100">
						<title>哈哈</title>
						<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
					</svg>
				);
			})}
		</div>
	);
}, '#root');
